<?php
namespace App\Http\Logic;

use App\Enums\OrderEnum;
use App\Logic\GoodsLogic;
use App\Logic\LogLogic;
use App\Models\SwtDheMachine;
use App\Models\SwtDheOrder;
use App\Models\SwtGood;
use App\Models\SwtOrder;
use App\Models\SwtOrderRefund;
use App\Models\SwtUser;
use App\Services\AliPayService;
use App\Services\DaHuangService;
use App\Services\WechatPayService;
use App\Services\ZhengYuanService;
use Illuminate\Support\Facades\Storage;
use Ramsey\Uuid\Uuid;

class OrderLogic extends BaseLogic
{
    /**
     * @notes 查询当前是否存在同一用户不同机器不同门的进行中订单
     * @param $user_id
     * @return bool
     * @author Evil丿
     * @date 2024/04/16 10:32
     */
    public static function getUserOrderStatus($user_id, $platform)
    {
        if($platform == 'card') {

            $res = UserLogic::getCardUserInfo($user_id);

            if($res === false) {
                self::$error = UserLogic::getErrorMessage();
            }
        }

        $order_info = SwtOrder::where('user_id', $user_id)
            ->where( function ($query) {
                $query-> where(function ($sql) {
                    $sql -> where('state', OrderEnum::ORDER_DOING);
                });
                $query-> orWhere( function ($sql) {
                    $sql -> orWhere('state', OrderEnum::ORDER_DONE) -> where('is_pay', 0);
                });
                $query-> orWhere( function ($sql) {
                    $sql -> orWhere('need_further_pay', 1);
                });
            })->first();

        if(empty($order_info)){
            return true;
        }

        if($order_info -> need_further_pay == 1) {
            self::$error = "用户需要补单";
        }

        if($order_info -> state == OrderEnum::ORDER_DONE && $order_info -> is_pay == 0) {
            self::$error = "存在未支付订单";
        }

        if($order_info -> state == OrderEnum::ORDER_DOING) {
            self::$error = "存在进行中订单";
        }

        return false;
    }

    /**
     * @notes 创建支付预订单
     * @param $platform
     * @param $user_id
     * @param $machine_id
     * @param $door_num
     * @return array|false
     * @author Evil丿
     * @date 2024/08/30 12:08
     */
    public static function createPayOrder($platform, $user_id, $machine_id, $door_num)
    {
        switch($platform)
        {
            case 'wechat' :
                $res = self::createWechatOrder($user_id, $machine_id, $door_num);
                break;
            case 'alipay' :
                $res = self::createAlipayOrder($user_id, $machine_id, $door_num);
                break;
            case 'card' :
                $res = self::createCardOrder($user_id, $machine_id, $door_num);
                break;
        }

        return $res;
    }

    /**
     * @notes 创建一卡通订单
     * @param $user_id
     * @param $machine_id
     * @param $door_num
     * @return array|false
     * @author Evil丿
     * @date 2025/01/07 17:48
     */
    public static function createCardOrder($user_id, $machine_id, $door_num)
    {
        $order_sn = MD5(Uuid::uuid4() -> toString());

        //订单添加数据库
        $order_info = [
            'user_id'       => $user_id,
            'state'         => OrderEnum::ORDER_CREATED,
            'machine_id'    => $machine_id,
            'door_num'      => $door_num,
            'order_sn'      => $order_sn,
            'platform'      => 'card',
            'pay_type'      => 2
        ];

        $order_id = OrderLogic::createOrderInfo($order_info);

        //订单创建失败则取消支付分订单
        if(!$order_id) {
            self::$error = "系统订单创建失败";
            return false;
        }

        $order_info['id'] = $order_id;
        $order_info['auth_params'] =  ['order_id' => $order_id];

        return $order_info;
    }

    /**
     * @notes 创建支付宝授权订单
     * @param $user_id
     * @param $machine_id
     * @param $door_num
     * @return array|false
     * @author Evil丿
     * @date 2024/09/02 12:17
     */
    public static function createAlipayOrder($user_id, $machine_id, $door_num)
    {
        $order_sn = MD5(Uuid::uuid4() -> toString());

        $pay = new AliPayService();

        $res = $pay -> getAuthParams($order_sn, $machine_id);

        if($res === false) {
            self::$error = "支付分订单创建失败";
            return false;
        }

        //订单添加数据库
        $order_info = [
            'user_id'       => $user_id,
            'state'         => OrderEnum::ORDER_CREATED,
            'machine_id'    => $machine_id,
            'door_num'      => $door_num,
            'order_sn'      => $order_sn,
            'platform'      => 'alipay'
        ];

        $order_id = OrderLogic::createOrderInfo($order_info);

        //订单创建失败则取消支付分订单
        if(!$order_id) {
            self::$error = "系统订单创建失败";
            return false;
        }

        $data['order_id'] = $order_id;
        $data['signStr'] = $res;

        $order_info['id'] = $order_id;
        $order_info['auth_params'] =  $data;

        return $order_info;
    }

    /**
     * @notes 创建微信支付分订单
     * @param $user_id
     * @param $machine_id
     * @param $door_num
     * @return array|false
     * @author Evil丿
     * @date 2024/09/02 12:16
     */
    public static function createWechatOrder($user_id, $machine_id, $door_num)
    {
        $order_sn = MD5(Uuid::uuid4() -> toString());

        $pay = new WechatPayService();

        $res = $pay -> createOrder($order_sn);

        if($res === false) {
            self::$error = "支付分订单创建失败";
            return false;
        }

        //订单添加数据库
        $order_info = [
            'user_id'       => $user_id,
            'state'         => OrderEnum::ORDER_CREATED,
            'machine_id'    => $machine_id,
            'door_num'      => $door_num,
            'order_sn'      => $order_sn,
            'platform'      => 'wechat',
            'pay_order_id'  => $res['order_id']
        ];

        $order_id = OrderLogic::createOrderInfo($order_info);

        //订单创建失败则取消支付分订单
        if(!$order_id) {
            self::$error = "系统订单创建失败";
            $pay -> cancelOrder($order_sn, '商户订单创建失败');
            return false;
        }

        $order_info['id'] = $order_id;
        $order_info['auth_params'] =  $pay -> getAuthParams($res['package'], $order_id);

        return $order_info;
    }

    /**
     * @notes 获取订单实际状态并更新数据库
     * @param $order_sn
     * @param $platform
     * @return false
     * @author Evil丿
     * @date 2024/08/30 13:04
     */
    public static function getOrderAuthStatus($order_sn, $platform, $confirm)
    {
        switch($platform) {
            case 'wechat' :
                $pay = new WechatPayService();

                $pay_info = $pay -> getOrder($order_sn);

                if($pay_info === false) {
                    self::$error = "查询订单失败";
                    return false;
                }

                if($pay_info['state'] == OrderEnum::ORDER_CREATED) {
                    self::$error = "用户取消授权";
                    return false;
                }
                break;
            case 'alipay' :
                $params = json_decode($confirm, true);

                $params = $params['alipay_user_agreement_page_sign_response'];

                $pay_info = OrderLogic::editOrderState($params);
                break;
            case 'card' :
                $params = [
                    'status'                => "NORMAL",
                    'external_agreement_no' => $order_sn,
                    'agreement_no'          => ""
                ];

                $pay_info = OrderLogic::editOrderState($params);
                break;
        }

        $update = [
            'state'             => $pay_info['state'],
            'state_description' => $pay_info['state_description'] ?? ""
        ];

        $res = SwtOrder::where('order_sn', $order_sn) -> update($update);

        if($res === false) {
            self::$error = "订单更新失败";
            return false;
        }

        return $pay_info['state'];
    }

    /**
     * @notes 获取订单及用户设备信息
     * @param $order_id
     * @return array|false
     * @author Evil丿
     * @date 2024/08/30 12:55
     */
    public static function getOrderWithUserInfo($order_id)
    {
        $order_info = SwtOrder::with(['user','machine'])->find($order_id);

        if(!$order_info) {
            self::$error = "订单不存在";
            return false;
        }

        return $order_info -> toArray();
    }

    /**
     * @notes 获取订单信息
     * @param $order_id
     * @return false
     * @author Evil丿
     * @date 2024/08/30 14:13
     */
    public static function getOrderInfo($order_id)
    {
       $order_info =  SwtOrder::find($order_id);

       if(!$order_info) {
           self::$error = "订单不存在";
           return false;
       }

       return $order_info -> toArray();
    }

    /**
     * @notes 修改订单状态
     * @param $params
     * @return array|false
     * @author Evil丿
     * @date 2024/09/02 17:39
     */
    public static function editOrderState($params)
    {
        $order_info = SwtOrder::firstWhere('order_sn', $params['external_agreement_no']);

        if($order_info -> state == OrderEnum::ORDER_REVOKED) {
            $order_info -> pay_order_id = $params['agreement_no'];
            $order_info -> save();

            OrderLogic::cancelOrder($order_info -> order_sn, $order_info -> door_num, $order_info->platform);

            return [
                'state' => OrderEnum::ORDER_REVOKED,
                'state_description' => ''
            ];
        }

        if($params['status'] == 'NORMAL' && $order_info -> pay_order_id == null) {
            $order_info -> pay_order_id = $params['agreement_no'];
            $order_info -> state = OrderEnum::ORDER_DOING;
            $order_info -> state_description = OrderEnum::ORDER_USER_CONFIRM;
            $order_info -> save();
        }

        return [
            'state' => OrderEnum::ORDER_DOING,
            'state_description' => OrderEnum::ORDER_USER_CONFIRM
        ];
    }

    /**
     * @notes 获取订单信息
     * @param $order_id
     * @return array|false
     * @author Evil丿
     * @date 2024/07/30 10:25
     */
    public static function getOrderDetail($order_id)
    {
        $order_info = SwtOrder::with(['goods','machine']) -> firstWhere('id', $order_id);

        if(!$order_info) {
            self::$error = "订单信息不存在";
            return false;
        }

        $status = 0;

        if($order_info -> is_pay) {
            $status = 1;
        }

        $refund_amount = (float) bcdiv($order_info -> refund_amount, 100 ,2);

        if($refund_amount > 0) {
            $refund_amount = (float) bcdiv(bcsub($order_info -> pay_amount, $order_info -> refund_amount),100, 2);
            $status = 3;
        }

        if($order_info -> is_refund) {
            $status = 2;
        }

        $order_refund_info = SwtOrderRefund::where('order_id', $order_info -> id) -> where('status', 0) -> first();

        if($order_refund_info) {
            $status = 4;
        }

        $goods_list = [];

        foreach($order_info -> goods as $v) {
            $goods_picture = SwtGood::where('id', $v -> goods_id) -> value('goods_picture');

            if(!$goods_picture) {
                $goods_picture = "/images/logo.png";
            }

            $goods_list[] = [
                'goods_picture' => Storage::url($goods_picture),
                'goods_name'    => $v -> goods_name,
                'goods_num'     => $v -> goods_num,
                'goods_price'   => (float) bcdiv($v -> goods_price / $v -> goods_num, 100, 2)
            ];
        }

        $order_detail = [
            'id'                => $order_info -> id,
            'status'            => $status,
            'pay_amount'        => (float) bcdiv($order_info -> pay_amount, 100, 2),
            'order_amount'      => (float) bcdiv($order_info -> order_amount, 100, 2),
            'refund_amount'     => $refund_amount,
            'order_sn'          => $order_info -> created_at -> format('YmdHis') . $order_info -> id,
            'create_time'       => $order_info -> created_at -> format('Y-m-d H:i:s'),
            'payment_time'      => $order_info -> payment_at,
            'machine_name'      => $order_info -> machine -> nickname,
            'machine_address'   => $order_info -> machine -> address ?? '',
            'goods_list'        => $goods_list,
            'platform'          => $order_info -> platform
        ];

        return $order_detail;
    }

    /**
     * @notes 获取订单列表
     * @param $user_id
     * @param $data
     * @return array
     * @author Evil丿
     * @date 2024/08/05 14:59
     */
    public static function getOrderList($user_id, $data)
    {
        $page_no = 1;

        if(key_exists('page_no', $data)) {
            $page_no = $data['page_no'];
        }

        $page_size = 10;

        if(key_exists('page_size', $data)) {
            $page_size = $data['page_size'];
        }

        $where = [
            ['state','=',OrderEnum::ORDER_DONE],
            ['user_id','=',$user_id]
        ];

        $offset = ($page_no - 1) * $page_size;

        $list = SwtOrder::where($where) ->whereIn('state_description', [OrderEnum::ORDER_MCH_COMPLETE, OrderEnum::JSAPI])-> orderBy('created_at','desc') -> offset($offset) -> limit($page_size) -> get();

        $order_list = [];

        foreach($list as $v) {
            $order_list[] = self::getOrderDetail($v['id']);
        }

        return $order_list;
    }

    /**
     * @notes 新增订单
     * @param $data
     * @return mixed
     * @author Evil丿
     * @date 2024/04/16 14:31
     */
    public static function createOrderInfo($data)
    {
        $order = SwtOrder::create($data);
        return $order -> id;
    }

    /**
     * @notes 获取最后一条进行中订单
     * @param $user_id
     * @return false|Object
     * @author Evil丿
     * @date 2024/05/30 15:44
     */
    public static function getLastDoingOrder($user_id, $source_type, $device_code)
    {
        $where = [
            ['user_id' , $user_id],
            ['state' , OrderEnum::ORDER_DOING],
        ];

        if($device_code) {
            switch($source_type) {
                case 1:
                    $machine_info = SwtDheMachine::with('machine') -> firstWhere('device_code', $device_code);
                    $where[] = ['machine_id', $machine_info -> machine -> id];
                break;
            }
        }

        $order_info = SwtOrder::where($where) -> orderBy('created_at','desc') -> first();

        if(!$order_info) {
            return false;
        }

        return $order_info;
    }

    public static function addSupplementOrder($reqId, $params, $source_type)
    {
        $content = false;

        switch($source_type) {
            case 1 :
                 if($params['device_code']) {
                     $machine_info = SwtDheMachine::with('machine') -> firstWhere('device_code', $params['device_code']);

                     $user_info = SwtUser::firstWhere('id', $params['memberNo']);

                     $order_info = [
                         'user_id'    => $user_info->id,
                         'machine_id' => $machine_info->machine_id,
                         'door_num'   => 1,
                         'is_warning' => 1,
                         'pay_type'   => 1,
                         'order_sn'   => $params['outTradeNo'],
                         'platform'   => $user_info -> wechat_open_id ? 'wechat' : 'alipay',
                         'state'      => OrderEnum::ORDER_DOING,
                         'order_amount' => $params['totalAmount'],
                         'state_description' => OrderEnum::ORDER_USER_CONFIRM,
                         'need_further_pay'  => 1,
                         'further_pay_money' => $params['totalAmount']
                     ];

                     $order_id = self::createOrderInfo($order_info);

                     GoodsLogic::addOrderGoods($order_id, $params['goodsInfos'], $source_type);

                     $content = DheOrderLogic::hasNotifyOrder($params['outTradeNo']);

                     if(!$content) {
                         DheOrderLogic::setNotifyOrder($order_id, $reqId, $params);
                         $content = [
                             'tradeNo'       => $params['outTradeNo'],
                             'outTradeNo'    => $params['outTradeNo'],
                             'orderStatus'   => 'NO_PAY',
                             'totalAmount'   => $params['totalAmount'],
                             'memberNo'      => $params['memberNo'],
                             'paidTime'      => date('Y-m-d H:i:s', time())
                         ];
                     }
                 }
            break;
        }

        return $content;
    }

    /**
     * @notes  订单退款
     * @param $out_order_no
     * @param $amount
     * @return false|mixed|string
     * @author Evil丿
     * @date 2024/04/16 14:31
     */
    public static function refundOrder($out_order_no, $amount, $reason = "")
    {
        $order_info = SwtOrder::with('machine') -> firstWhere('order_sn', $out_order_no);

        if($order_info -> is_pay == 0) {
            return false;
        }

        if($order_info -> is_refund == 1) {
            return false;
        }

        $out_refund_no = MD5($out_order_no.$amount.time());

        $transaction_id = $order_info -> transaction_id;

        $total = $order_info -> pay_amount;

        switch($order_info -> platform) {
            case 'wechat' :
                $pay = new WechatPayService();

                $res = $pay -> refundOrder( $transaction_id, $out_refund_no, $amount, $total, $reason);
                break;
            case 'alipay' :
                $pay = new AlipayService();

                $res = $pay -> refundOrder($transaction_id, $out_refund_no, $amount, $reason);
                break;
            case 'card' :
                $pay = new ZhengYuanService();

                $res = $pay -> refundOrder($order_info -> pay_order_id, $out_refund_no , $amount / 100);

                if($res) {
                    $user_info = SwtUser::firstWhere('id', $order_info -> user_id);

                    LogLogic::setZyLogs($order_info -> order_sn, $user_info->card_id, $amount / 100 * -1, '订单付款');
                }
        }


        if($res === false) {
            return false;
        }

        $refund_amount = $order_info -> refund_amount + $amount;

        $order_info -> is_refund = $refund_amount == $order_info -> pay_amount ? 1 : 0;
        $order_info -> refund_amount = $refund_amount;
        $order_info -> refund_at = date('Y-m-d H:i:s', time());
        $order_info -> save();

        //退款成功后退还收益
        MerchantLogic::setMerchantProfit($order_info -> machine -> id, $amount, $order_info -> id, $order_info -> order_sn, 1) ;

        return true;
    }

    /**
     * @notes 订单退款
     * @return bool
     * @author Evil丿
     * @date 2024/08/06 14:04
     */
    public static function refundOrderByJsApi($out_trade_no, $amount, $reason = "")
    {
        $order_info = SwtOrder::where('out_trade_no', $out_trade_no)->first();

        if($order_info -> is_pay == 0) {
            return false;
        }

        if($order_info -> is_refund == 1) {
            return false;
        }

        $out_refund_no = MD5($out_trade_no.$amount.time());

        $transaction_id = $order_info -> transaction_id;

        $total = $order_info -> pay_amount;

        $pay = new WechatPayService();

        $res = $pay->refundOrder( $transaction_id, $out_refund_no, $amount, $total, $reason);

        if($res === false) {
            return false;
        }

        $refund_amount = $order_info -> refund_amount + $amount;

        $order_info -> is_refund = $refund_amount == $order_info -> pay_amount ? 1 : 0;
        $order_info -> refund_amount = $refund_amount;
        $order_info -> refund_at = date('Y-m-d H:i:s', time());
        $order_info -> save();

        return true;
    }

    /**
     * @notes 取消订单
     * @param $out_order_no
     * @param $door_num
     * @param $platform
     * @return void
     * @author Evil丿
     * @date 2024/08/30 15:25
     */
    public static function cancelOrder($out_order_no, $door_num, $platform)
    {
        MachineLogic::clearMachineCacheLock($out_order_no, $door_num);

        $info = SwtOrder::with('user')->firstWhere('order_sn', $out_order_no);

        if($info -> pay_type == 0) {
            switch($platform)
            {
                case 'wechat' :
                    $pay = new WechatPayService();
                    $res = $pay -> getOrder( $out_order_no );
                    if($res && in_array($res['state'], [OrderEnum::ORDER_CREATED, OrderEnum::ORDER_DOING])) {
                        $pay->cancelOrder( $out_order_no );
                    }
                    break;
                case 'alipay' :
                    $pay = new AliPayService();
                    $res = $pay -> getOrder($out_order_no, $info -> user -> alipay_open_id);
                    if($res && in_array($res['state'], [OrderEnum::ORDER_CREATED, OrderEnum::ORDER_DOING])) {
                        $pay->cancelOrder($out_order_no, $info -> user -> alipay_open_id);
                    }
                    break;
                case 'card' :
                    break;
            }
        }

        $update = [
            'state'                  => OrderEnum::ORDER_REVOKED,
            'is_warning'             => 0,
            'need_further_pay'       => 0,
            'further_pay_money'      => 0
        ];

        SwtOrder::where('order_sn', $out_order_no) -> update($update);
    }

    /**
     * @notes 设置订单异常
     * @param $out_order_no
     * @param $door_num
     * @return void
     * @author Evil丿
     * @date 2024/08/30 15:30
     */
    public static function setWarningOrder($out_order_no, $door_num, $warning_desc = "")
    {
        MachineLogic::clearMachineCacheLock($out_order_no, $door_num);

        SwtOrder::where('order_sn', $out_order_no) -> update(['is_warning' => 1, "warning_desc" => $warning_desc ? : null]);
    }


    /**
     * @notes 订单发起支付
     * @param $pay_info
     * @return bool
     * @author Evil丿
     * @date 2024/05/30 15:44
     */
    public static function payOrder($order_id, $amount, $goods_info, $source_type)
    {
        GoodsLogic::addOrderGoods($order_id, $goods_info, $source_type);

        $update = [
            'state'             => OrderEnum::ORDER_DONE,
            'state_description' => OrderEnum::ORDER_MCH_COMPLETE,
            'order_amount'      => $amount
        ];

        $res = SwtOrder::where('id', $order_id) -> update($update);

        if($res === false) {
            self::$error = "订单信息修改失败";
            return false;
        }

        return true;
    }

    /**
     * @notes 完结订单
     * @param $finish_info
     * @return boolean
     * @author Evil丿
     * @date 2024/07/29 16:31
     */
    public static function finishOrder($finish_info, $platform)
    {
        switch($platform)
        {
            case 'wechat' :
               $res = self::finishWechatOrder($finish_info);
            break;
            case 'alipay' :
                $res = self::finishAlipayOrder($finish_info);
            break;
            case 'card' :
                $res = self::finishCardOrder($finish_info);
            break;
        }
        return $res;
    }

    /**
     * @notes 完结一卡通订单
     * @param $finish_info
     * @return bool
     * @throws \Illuminate\Http\Client\RequestException
     * @author Evil丿
     * @date 2025/01/07 17:38
     */
    public static function finishCardOrder($finish_info)
    {
        $order_info = SwtOrder::firstWhere('order_sn', $finish_info['out_trade_no']);

        if(!$order_info) {
            self::$error = "订单不存在";
            return false;
        }

        $payment_at = date('Y-m-d H:i:s', time());

        $update = [
            'is_pay'                => 1,
            'state'                 => 'DONE',
            'pay_order_id'          => $finish_info['pay_order_id'],
            'transaction_id'        => $finish_info['transaction_id'],
            'pay_amount'            => $finish_info['receipt_amount'] * 100,
            'payment_at'            => $payment_at
        ];

        $res = SwtOrder::where('id', $order_info -> id) -> update($update);

        if(!$res) {
            self::$error = "订单信息修改失败";
            return false;
        }

        //设备减少库存
        GoodsLogic::updateGoodsWeight($order_info -> id);
        //回调订单信息给大黄鹅
        self::notifyOrder($order_info -> id, $finish_info['out_trade_no'], $finish_info['receipt_amount'] * 100, $order_info -> user_id, $payment_at);
        //设备增加销量
        MachineLogic::addMachineAmountByOrderId($order_info -> machine_id, $order_info -> id);
        //回调订单信息给商户
        MerchantLogic::setMerchantProfit($order_info -> machine_id, $finish_info['receipt_amount'] * 100, $order_info -> id, $order_info -> order_sn);

        return true;
    }

    /**
     * @notes 支付宝订单完结
     * @param $finish_info
     * @return boolean
     * @throws \Illuminate\Http\Client\RequestException
     * @author Evil丿
     * @date 2024/09/03 14:04
     */
    public static function finishAlipayOrder($finish_info)
    {
        $order_info = SwtOrder::firstWhere('order_sn', $finish_info['out_trade_no']);

        if(!$order_info) {
            self::$error = "订单不存在";
            return false;
        }

        $payment_at = date('Y-m-d H:i:s', time());

        $update = [
            'is_pay'                => $finish_info['trade_status'] == 'TRADE_SUCCESS' ? 1 : 0,
            'state'                 => OrderEnum::getAlipayOrderState($finish_info['trade_status']),
            'transaction_id'        => $finish_info['trade_no'],
            'pay_amount'            => $finish_info['receipt_amount'] * 100,
            'payment_at'            => $payment_at
        ];

        $res = SwtOrder::where('id', $order_info -> id) -> update($update);

        if(!$res) {
            self::$error = "订单信息修改失败";
            return false;
        }

        //设备减少库存
        GoodsLogic::updateGoodsWeight($order_info -> id);
        //设备增加销量
        MachineLogic::addMachineAmountByOrderId($order_info -> machine_id, $order_info -> id);
        //回调订单信息给大黄鹅
        self::notifyOrder($order_info -> id, $finish_info['out_trade_no'], $finish_info['receipt_amount'] * 100, $order_info -> user_id, $payment_at);
        //回调订单信息给商户
        MerchantLogic::setMerchantProfit($order_info -> machine_id, $finish_info['receipt_amount'] * 100, $order_info -> id, $order_info -> order_sn);

        return true;
    }

    /**
     * @notes 微信订单完结
     * @param $finish_info
     * @return boolean
     * @throws \Illuminate\Http\Client\RequestException
     * @author Evil丿
     * @date 2024/09/03 14:04
     */
    public static function finishWechatOrder($finish_info)
    {
        $order_info = SwtOrder::firstWhere('order_sn', $finish_info['out_order_no']);

        if(!$order_info) {
            self::$error = "订单不存在";
            return false;
        }

        $pay_info = $finish_info['collection'];

        $payment_at = date('Y-m-d H:i:s', time());

        $update = [
            'is_pay'                => $pay_info['state'] == 'USER_PAID' ? 1 : 0,
            'state'                 => $finish_info['state'],
            'transaction_id'        => $pay_info['details'][0]['transaction_id'],
            'need_further_pay'      => $pay_info['paying_amount'] > 0 ? 1 : 0,
            'pay_amount'            => $pay_info['paid_amount'],
            'further_pay_money'     => $pay_info['paying_amount'],
            'payment_at'            => $payment_at
        ];

        $res = SwtOrder::where('id', $order_info -> id) -> update($update);

        if($res === false) {
            self::$error = "订单信息修改失败";
            return false;
        }

        //设备减少库存
        GoodsLogic::updateGoodsWeight($order_info -> id);
        //设备增加销量
        MachineLogic::addMachineAmountByOrderId($order_info -> machine_id, $order_info -> id);
        //回调订单信息给大黄鹅
        self::notifyOrder($order_info -> id, $finish_info['out_order_no'], $pay_info['paid_amount'],$order_info -> user_id, $payment_at);
        //回调订单信息给商户
        MerchantLogic::setMerchantProfit($order_info -> machine_id, $pay_info['paid_amount'], $order_info -> id, $order_info -> order_sn);

        return true;
    }

    /**
     * @notes 回调订单信息给DHE
     * @param $order_id
     * @param $out_order_no
     * @param $amount
     * @param $user_id
     * @param $payment_at
     * @return bool
     * @throws \Illuminate\Http\Client\RequestException
     * @author Evil丿
     * @date 2024/07/29 16:10
     */
    public static function notifyOrder($order_id, $out_order_no, $amount, $user_id, $payment_at)
    {
        $dhe_order = SwtDheOrder::firstWhere('order_id', $order_id);

        if(!$dhe_order) {
            return false;
        }

        $notify = DaHuangService::orderRefund($dhe_order -> notify_url, $out_order_no, $dhe_order -> out_trade_no, "PAY_SUCCESS", $amount, $user_id, $dhe_order -> attach, $payment_at);

        if($notify == 200) {
            SwtOrder::where('order_sn', $out_order_no) -> update(['is_notify' => 1]);
            return true;
        }

        return false;
    }


    /**
     * @notes 提交退款订单
     * @param $order_id
     * @param $user_id
     * @param $refund_amount
     * @param $notes
     * @return bool
     * @author Evil丿
     * @date 2024/07/31 14:01
     */
    public static function setRefundOrder($order_id, $user_id, $refund_amount, $notes = "")
    {
        $order_refund = SwtOrderRefund::where('order_id', $order_id) -> where('status', 0) -> first();

        if($order_refund) {
            self::$error = "已存在退款申请";
            return false;
        }

        $order_info = SwtOrder::where('id', $order_id) -> first();

        if(!$order_info) {
            self::$error = "原订单不存在";
            return false;
        }

        if($order_info -> is_pay == 0) {
            self::$error = "订单未支付";
            return false;
        }

        if($order_info -> is_refund == 1) {
            self::$error = "订单已退款";
            return false;
        }

        if($order_info -> pay_amount - $order_info -> refund_amount < $refund_amount) {
            self::$error = "退款金额不足";
            return false;
        }

        $data = [
            'order_id'      => $order_id,
            'user_id'       => $user_id,
            'refund_amount' => $refund_amount * 100,
            'notes'         => $notes
        ];

        $res = SwtOrderRefund::create($data);

        if(!$res) {
            self::$error = "提交申请失败";
            return false;
        }

        return true;
    }

    /**
     * @notes 获取退款订单详情
     * @param $order_id
     * @param $user_id
     * @return array|false
     * @author Evil丿
     * @date 2024/07/31 14:13
     */
    public static function getRefundOrderDetail($order_id, $user_id)
    {
        $detail = SwtOrderRefund::with('order')
            -> where('order_id',$order_id)
            -> where('user_id',$user_id)
            -> orderBy('created_at','desc')
            -> first();

        if(!$detail) {
            self::$error = "未找到订单信息";
            return false;
        }

        $data = [
            'order_sn'        => $detail->order->created_at->format('YmdHis') . $order_id,
            'refund_amount'   => (float)bcdiv($detail->refund_amount, 100, 2),
            'notes'           => $detail->notes,
            'refund_order_sn' => $detail->created_at->format('YmdHis') . $detail->id,
            'create_time'     => $detail->created_at->format('Y-m-d H:i:s'),
            'status'          => $detail->status,
            'reject_notes'    => $detail->reject_notes
        ];

        return $data;
    }

    /**
     * @notes 订单支付异常
     * @param $order_info
     * @param $goods_list
     * @param $amount
     * @param $source_type
     * @return void
     * @author Evil丿
     * @date 2024/08/30 16:08
     */
    public static function setAmountErrorOrder($order_info, $goods_list, $amount, $source_type)
    {
        $update = [
            'order_amount'          => $amount,
            'need_further_pay'      => 1,
            'further_pay_money'     => $amount
        ];

        SwtOrder::where('id', $order_info['id']) -> update($update);

        GoodsLogic::addOrderGoods($order_info['id'], $goods_list, $source_type);
    }

    /**
     * @notes 获取金额异常订单支付参数
     * @param $order_id
     * @param $platform
     * @return array|false
     * @author Evil丿
     * @date 2024/08/06 13:19
     */
    public static function payAmountErrorOrder($order_id, $platform)
    {
        $order_info = SwtOrder::with('user') -> where('id', $order_id) ->  first();

        if(!$order_info) {
            self::$error = "订单不存在";
            return false;
        }

        if($order_info -> need_further_pay == 0) {
            self::$error = "订单已经支付完成";
            return false;
        }

        $order_sn = MD5(Uuid::uuid4()->toString());

        SwtOrder::where('id', $order_id) -> update(['out_trade_no' => $order_sn]);

        switch ($platform) {
            case 'wechat' :
                $pay = new WechatPayService();
                $res = $pay ->payOrderByJsapi($order_sn, $order_info -> further_pay_money, $order_info -> user -> wechat_open_id);
                break;
            case 'alipay' :
                $pay = new AliPayService();
                $res = $pay ->payOrderByJsapi($order_sn, $order_info -> further_pay_money, $order_info -> user -> alipay_open_id);
                break;
        }

        return $res;
    }

    /**
     * @notes 完结金额异常订单
     * @param $params
     * @return string|true
     * @author Evil丿
     * @date 2024/08/06 13:26
     */
    public static function finishAmountErrorOrder($params, $platform)
    {
        try {
            $order_info = SwtOrder::with('user') -> firstWhere('out_trade_no', $params['out_trade_no']);

            if(!$order_info) throw new \Exception('订单不存在');

            $old_platform = $order_info -> platform;

            switch($platform) {
                case 'wechat' :
                    $state = $params['trade_state'] == "SUCCESS";
                    $trade_id = $params['transaction_id'];
                    $pay_amount = $params['amount']['payer_total'];

                    break;
                case 'alipay' :
                    $state = $params['trade_state'] == "TRADE_SUCCESS";
                    $trade_id = $params['trade_no'];
                    $pay_amount = $params['buyer_pay_amount'] * 100;

                    break;
            }

            if($state) {
                $update = [
                    'need_further_pay'  => 0,
                    'further_pay_money' => 0,
                    'is_pay'            => 1,
                    'is_warning'        => 0,
                    'payment_at'        => date('Y-m-d H:i:s', time()),
                    'pay_type'          => 1,
                    'is_notify'         => 1,
                    'platform'          => $platform,
                    'state'             => OrderEnum::ORDER_DONE,
                    'state_description' => OrderEnum::JSAPI,
                    'pay_amount'        => $pay_amount,
                    'transaction_id'    => $trade_id,
                ];

                $res = SwtOrder::where('out_trade_no', $params['out_trade_no'])->update($update);

                if ($res === false) throw new \Exception('订单信息修改失败');

                switch($old_platform) {
                    case 'wechat' :
                        $pay = new WechatPayService();
                        $pay->cancelOrder( $order_info -> order_sn );
                    break;
                    case 'alipay' :
                        $pay = new AliPayService();
                        $pay->cancelOrder( $order_info -> order_sn, $order_info->user->alipay_open_id );
                    break;
                }

                MachineLogic::addMachineAmountByOrderId($order_info->machine_id, $order_info->id);

                //回调订单信息给大黄鹅
                self::notifyOrder($order_info->id, $params['out_trade_no'], $pay_amount, $order_info->user_id, date('Y-m-d H:i:s', time()));
                //回调订单信息给商户
                MerchantLogic::setMerchantProfit($order_info->machine_id, $pay_amount, $order_info->id, $params['out_trade_no']);

                MachineLogic::clearMachineCacheLock($order_info->order_sn, $order_info->door_num);
            }

            return true;
        } catch(\Exception $e) {
            return $e -> getMessage();
        }
    }
}
